str = "add_(1,add_(1,add_(1)))"
vars=[]
class String

def in_reg
@regs = [/\#set\(.*\)/,/#eval\(.*\)/,/\%x\(.*\)/,/\%v\([0-9]+\)/]
ret = false
i = 0
 @regs.each {|r|
   if self =~ r
     i=i+1
   end
 }
 ret = 1 if i >= 1
ret
end
end
require '/home/ppibburr/muide1/libs/utilities/main/mucode'
$procs = {}
# $procs["reg"]=proc do |*args|
#   
# end
# $procs["add_"]=proc do |*args|
# 
# en
# $procs["add_"]=proc do |*args|
# 
# end
# $procs["add_"]=proc do |*args|
# 
# end
# $procs["add_"]=proc do |*args|
# 
# end
$procs["add_"]=proc do |*args|
 ct = 0
 args.each {|a|
   ct = ct + a.to_i
 }
 return ct.to_s
end
class Function
  attr_accessor :current_param,:params
  def initialize function,procs
    @procs = procs
    @params = [""]
    @function = function
p function
    @current_param = 0
  end
  def evaluate
    @procs[@function].call(*@params)
  end
  def next_param
    @params << ""
    @current_param = @params.length-1
  end
end
class Eval
 attr_accessor :value,:functions
  def initialize str
    @tokens = Tokenizer.tokenize(str)
    @value = ""
    @functions = []
    @function=0
    @open_functions = []
  end
  def evaluate 
    @tokens.each {|t|
      case t[1]
         when :function_start
           @functions << Function::new(t[0][0..t[0].length-2],$procs)
           @open_functions << @functions.last
           @last_function = @functions.last
           @function = @function + 1
         when :function_param_sep
           @last_function.next_param
         when :function_end
           @function = @function - 1
           value = @last_function.evaluate
#            p @last_function.params
           @open_functions.delete(@last_function)
#            p value
          if @open_functions!=[]
             @last_function = @open_functions.last
             @last_function.params[@last_function.current_param] = @last_function.params[@last_function.current_param]+value
#              p @last_function.current_para
           else
             @value=@value+value
           end
      else
        if @function > 0 
          @last_function.params[@last_function.current_param] = @last_function.params[@last_function.current_param]+t[0]
#           p @last_function.current_param+"00000"
        else
          @value = @value+t[0]
        end
      end
    }
  end
end

e = Eval::new(str)
e.evaluate
p e.value
p e.functions




#       while str=~/\#set\(.*\)/ or str =~ /#eval\(.*\)/  or str =~ /\%x\(.*\)/ or str =~ /\%v\([0-9]+\)/
# # case str
#          if str =~ /\%x\((.*?)\)/
# p $1
# p $1.in_reg
#            str.gsub!("%x(#{$1})",eval("%x[#{$1}]")) unless $1.in_reg
#          end
#          if str =~ /#eval\((.*?)\)/
#            foo = $1
#            str.gsub!("#eval(#{foo})",eval(foo)) unless $1.in_reg
#          end
#          if str =~ /\#set\(([0-9]+)\,(.*?)\)/
#            vars[$1.to_i] = $2
#            str.gsub!("#set(#{$1},#{$2})",'') unless $1.in_reg
#          end  
# #          if str =~ /\%v\(([0-9]+)\)/
# #             if vars!=[] and vars!=nil and vars.class == Array
# #               str.gsub!("%v(#{$1})",vars[$1.to_i]) unless $1.in_reg
# #             else
# # #               $app.get_top_window.append_log "SUBSTITUTION VARIABLE #{$1} Not set"
# # #               break
# #             end
# #          end
# #  p str
#        end
# p str
# p vars